//
//  TestAsync.m
//  Facebook
//
//  Created by Wei Jian Heng on 3/10/11.
//  Copyright 2011 NUS. All rights reserved.
//

#import <GHUnitIOS/GHUnit.h>
#import "Api.h"
#import "User.h"
#import "Event.h"
#import "Comment.h"

@interface TestAsync : GHAsyncTestCase <ApiDelegate> { }
	Api *api;
	NSMutableArray *apiResults;
	NSString *testFunction;
	NSString *errorMessage;
@end

@implementation TestAsync


// Coded: WeiJian Heng ...Test Harness
const int TIMEOUT = 5;

- (void)setUp {
	api = [[Api alloc]initWithBaseUser:@"http://localhost:3000/"];
	api.delegate = self;
}


-(void)apiResultsReturnedInArray:(NSArray*)results {
	apiResults = [results retain];
	[self notify:kGHUnitWaitStatusSuccess forSelector:NSSelectorFromString(testFunction)];
}
-(void)apiRequestFailedWithError:(NSString*)apiErrorMessage {
	errorMessage = [apiErrorMessage retain];
	[self notify:kGHUnitWaitStatusSuccess forSelector:NSSelectorFromString(testFunction)];
}


- (void)tearDown {
	// Run after each test method
	[api release];
	[apiResults release];
	[testFunction release];
	[errorMessage release];
}


// Coded: Rollen Gomes ...API TESTING ...MODEL TESTING
-(User *) makeUser{
	User *u = [[[User alloc] init] autorelease];
	u.fid = @"100002290772035";
	u.accessToken = @"eSdD4dRjk7WrbsoRokqr291zzuzats6tGjGxqNm2B8E.eyJpdiI6ImttdVhnRW1pWTNKQ0VuSXdVWnhOeUEifQ.M_U41iMrfcBXl-zBaoLnynxAvbSanGRcuLqqI4NK5TuIp2Jcegu3GzaY4ftrLcvy9nkAczyMX-_ToZeo_ZNVdfeEZDcTvGmIlub2ZPLqpN6x2GrOyUlae-1DCZSE0Yg17xM5gD0oq5tLhN5ffizj8g";
	u.name = @"Hero";
	return u;
}

-(User *) makeUser2{
	User *u = [[[User alloc] init] autorelease];
	u.fid = @"100001664250948";
	u.accessToken = @"Bw5uAC80rNBDd2-1eHpKcDULalCSzEoodt6JqwQvAAs.eyJpdiI6Ii1ZY1Q5MzZEODIzWXc4VmM0LWVXVncifQ.MsyAindF3nh5PhxE2RjORoTIdINFk7djFgVHIibLHAcs8B-Fe-csSMCgYKFUcos5NJ5xWJ0-F-gAlZx6cXVylCnixUUYxOFrDPJzTXl9sbhpjQJfQaHBR2XMnGjcwtkc";
	u.name = @"jimsparrow";
	return u;
}
-(void) testThataUserCanBeCreatedAndThenDeletedAlsoThatWeCanGetAllUsers{

	User *u = [self makeUser];
	[u saveRemote];
	
	NSMutableArray *users = [NSMutableArray arrayWithArray:[User findAllRemote]];
	NSLog(@"I have %d users", users.count);
	
	BOOL found = NO;
	User *foundUser = nil;
	for(User *user in users){
		if( [user.fid isEqualToString:u.fid] ){
			found = YES;
			foundUser = user;
		}
	}
	GHAssertTrue(found, @"", @"");
	
	[foundUser destroyRemote];
	
}	


-(Event *) makeEvent{
	Event *event = [[[Event alloc] init] autorelease];
	event.organizer = @"Rollen";
	event.title = @"Title";
	event.commitee = @"CS3217 Team";
	event.description = @"Lots of Coding";
	event.venue = @"Tianwei's house";
	event.price = @"Way more than its worth";
	event.agenda = @"Lots of stuff to do";
	event.contact = @"Anyone but rollen";
	event.srcFileName = @"";
	event.srcContentType  = @""; 
	event.lat = 1.352184;                                                                                  
	event.lon =  103.819837;

	event.dateStart = [NSDate date];
	event.dateEnd = [NSDate date];
	
	return event;
}

-(Event *) makeEvent2{
	Event *event = [[[Event alloc] init] autorelease];
	event.organizer = @"Tianwei";
	event.title = @"Prjoct";
	event.commitee = @"EE4218 Team";
	event.description = @"Hardware time";
	event.venue = @"Tianwei's Lab";
	event.price = @"Sleep";
	event.agenda = @"Lots of stuff to do dum dum dum";
	event.contact = @"Tianwei";
	event.srcFileName = @"";
	event.srcContentType  = @""; 
	event.lat =1.352184;                                                                                  
	event.lon =  103.819838;
	
	event.dateStart = [NSDate date];
	event.dateEnd = [NSDate date];
	
	return event;
}

-(void) testThataEventCanBeCreatedAndThenDeletedAlsoThatWeCanGetAllEvents{
	// @synthesize title, organizer, commitee, category, description, venue, price, agenda, contact, srcFileName, srcContentType;
	Event *event = [self makeEvent];
	[event saveRemote];
	
	
	NSMutableArray *events = [NSMutableArray arrayWithArray:[Event findAllRemote]];
	NSLog(@"I have %d users", events.count);
	
	BOOL found = NO;
	Event *foundEvent = nil;
	for(Event *e in events){
		if( [e.eventId isEqualToString:event.eventId] ){
			found = YES;
			foundEvent = e;
		}
	}
	GHAssertTrue(found, @"", @"");
	
	[foundEvent destroyRemote];
}

-(void) testThatWeCanSignUpAUserForAnEvent{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *u = [self makeUser];
	[u saveRemote];

	[u registerForEvent:event];
	
	NSMutableArray *users = [NSMutableArray arrayWithArray:[User findAllRemote]];
	NSLog(@"I have %d users", users.count);
	
	User *foundUser = nil;
	for(User *us in users){
		if( [us.fid isEqualToString:u.fid] ){
			foundUser = us;
		}
	}
	
	GHAssertNotNil(foundUser, @"", @"");
	//NSLog(@"I have registered for %d events", foundUser.events.count);
	GHAssertTrue(foundUser.events.count == 1, @"", @"");
	[event destroyRemote];
	[u destroyRemote];
}

-(void) testThatWeCanSignUpAUserForAnEventOnlyUsingFid{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *u = [self makeUser];
	[u saveRemote];
	
	[api registerUser:u.fid ForEvent:event.eventId];
	
	NSMutableArray *users = [NSMutableArray arrayWithArray:[User findAllRemote]];
	NSLog(@"I have %d users", users.count);
	
	User *foundUser = nil;
	for(User *us in users){
		if( [us.fid isEqualToString:u.fid] ){
			foundUser = us;
		}
	}
	
	GHAssertNotNil(foundUser, @"", @"");
	//NSLog(@"I have registered for %d events", foundUser.events.count);
	GHAssertTrue(foundUser.events.count == 1, @"", @"");
	[event destroyRemote];
	[u destroyRemote];
}

-(void) testThatWeCanSignUpAUserForAnEventAndThenUnregisterForTheEvent{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *u = [self makeUser];
	[u saveRemote];
	
	[u registerForEvent:event];
	
	NSMutableArray *users = [NSMutableArray arrayWithArray:[User findAllRemote]];
	NSLog(@"I have %d users", users.count);
	
	User *foundUser = nil;
	for(User *us in users){
		if( [us.fid isEqualToString:u.fid] ){
			foundUser = us;
		}
	}
	
	GHAssertNotNil(foundUser, @"", @"");
	GHAssertTrue(foundUser.events.count == 1, @"", @"");
	
	
	[u unregisterForEvent:event];
	
	users = [NSMutableArray arrayWithArray:[User findAllRemote]];
	NSLog(@"I have %d users", users.count);
	
	foundUser = nil;
	for(User *us in users){
		if( [us.fid isEqualToString:u.fid] ){
			foundUser = us;
		}
	}
	
	GHAssertNotNil(foundUser, @"", @"");
	GHAssertTrue(foundUser.events.count == 0, @"", @"");
	
	[event destroyRemote];
	[u destroyRemote];
}


-(void) testfilteredEvents{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *user = [self makeUser];
	[user saveRemote];
	
	[api registerUser:user.fid ForEvent:event.eventId];
	NSArray *events = [api filteredEvents:user.accessToken];
	
	[user destroyRemote];
	[event destroyRemote];
}

-(void) testThatWeCanSignUpAUserForAnEventAndThenUnregisterForTheEventWithFacebookId{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *u = [self makeUser];
	[u saveRemote];
	
	[u registerForEvent:event];
	
	NSMutableArray *users = [NSMutableArray arrayWithArray:[User findAllRemote]];
	NSLog(@"I have %d users", users.count);
	
	User *foundUser = nil;
	for(User *us in users){
		if( [us.fid isEqualToString:u.fid] ){
			foundUser = us;
		}
	}
	
	GHAssertNotNil(foundUser, @"", @"");
	GHAssertTrue(foundUser.events.count == 1, @"", @"");
	
	
	[api unregisterUser:u.fid ForEvent:event.eventId];
	
	users = [NSMutableArray arrayWithArray:[User findAllRemote]];
	NSLog(@"I have %d users", users.count);
	
	foundUser = nil;
	for(User *us in users){
		if( [us.fid isEqualToString:u.fid] ){
			foundUser = us;
		}
	}
	
	GHAssertNotNil(foundUser, @"", @"");
	GHAssertTrue(foundUser.events.count == 0, @"", @"");
	
	[event destroyRemote];
	[u destroyRemote];
}

-(void) testEventCallFromProductionServer{
	Api *prod = [[Api alloc] init];
	
	NSArray *events = [prod getEvents];
	
	NSLog(@"Number of events: %d", events.count);
	GHAssertTrue(events.count > 0, @"", @"");
}


-(void) testThatAUserCanCommentOnAEvent{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *u = [self makeUser];
	[u saveRemote];
	
	Comment *comment = [[Comment alloc] init];
	comment.description = @"Hello World";
	comment.userId = u.userId;
	comment.eventId = event.eventId;
	
	[comment saveRemote];
	
	NSMutableArray *events = [NSMutableArray arrayWithArray:[Event findAllRemote]];
	//GHAssertTrue(events.count == 1, @"", @"");
		
	NSLog(@"%d", events.count);
	Event *newEvent = [events objectAtIndex:0];
	Comment *newComment = [newEvent.comments objectAtIndex:0];
	
	GHAssertTrue([comment.description isEqualToString:newComment.description], @"", @"");
	
	Event *aevent = [Event findRemote:newEvent.eventId];
	Comment *c = [aevent.comments objectAtIndex:0];
	User *sim = c.user;
	GHAssertNotNil(sim, @"", @"");
	
	[event destroyRemote];
	[u destroyRemote];
	[comment destroyRemote];
}

-(void) testThatAUserCanCommentOnAEventUsingApi{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *u = [self makeUser];
	[u saveRemote];
	
	[api addComment:@"My comment" from:u.fid toEvent:event.eventId];
	
	NSMutableArray *events = [NSMutableArray arrayWithArray:[Event findAllRemote]];
	
	NSLog(@"%d", events.count);
	Event *newEvent = [events objectAtIndex:0];
	Comment *newComment = [newEvent.comments objectAtIndex:0];
	
	//GHAssertTrue([comment.description isEqualToString:newComment.description], @"", @"");
	
	Event *aevent = [Event findRemote:newEvent.eventId];
	Comment *c = [aevent.comments objectAtIndex:0];
	User *sim = c.user;
	GHAssertNotNil(sim, @"", @"");
	
	[event destroyRemote];
	[u destroyRemote];
	//[comment destroyRemote];
}


-(void) testThatWeCanRemoveAnEvent{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	[api deleteEvent:event.eventId];
}

-(void) testThatAnEventCanHaveGeoBeParsed{
	Event *event = [self makeEvent];
	event.lat = 123.450;
	event.lon = 127.123;
	[event saveRemote];
	
	NSMutableArray *events = [NSMutableArray arrayWithArray:[Event findAllRemote]];
	//GHAssertTrue(events.count == 1, @"", @"");
	
	NSLog(@"%d", events.count);
	Event *newEvent = [events objectAtIndex:0];
	GHAssertTrue(newEvent.lat == 123.450, @"", @"");
	GHAssertTrue(newEvent.lon == 127.123, @"", @"");	
	
	[event destroyRemote];
}


-(Category *)makeCategory{
	Category *cat = [[Category alloc] init];
	cat.name = @"Bashes";
//	cat.categoryId = @"1";
	return cat;
	
}

-(void) testThatAnEventCanHaveACategory{
	Event *event = [self makeEvent];
	
	
	Category *category = [self makeCategory];
	[category saveRemote];
	
	NSMutableArray *categories = [NSMutableArray arrayWithArray:[Category findAllRemote]];
	Category *cat = [categories objectAtIndex:0];
	
	event.categoryId = cat.categoryId;
	
	[event saveRemote];
	
	[category destroyRemote];
	[event destroyRemote];
}


-(void) testThatWeCanGetAllCategoriesFromProduction{
	Api *prod = [[Api alloc] init];
	
	NSArray *cats = [Category findAllRemote];
	
	NSLog(@"Number of events: %d", cats.count);
	GHAssertTrue(cats.count == 14, @"", @"");
	
}

-(void) testthatAUserCanGetHisOwnEvents{
	Event *event = [self makeEvent];
	[event saveRemote];
	
	User *u = [self makeUser];
	[u saveRemote];
	
	[u registerForEvent:event];
	
	NSLog(@"%@", u.fid);
	NSArray *events = [api getEventsOfUserWithFacebookId:u.fid];
	
	GHAssertTrue(events.count == 1, @"", @"");
	
	[event destroyRemote];
	[u destroyRemote];
	
}

-(void) testThatAUSerCanSeeTheEventsTheHeCreated{
	User *u = [self makeUser];
	[u saveRemote];
	
	Event *event = [self makeEvent];
	event.createdBy = u.fid;
	[event saveRemote];
	
	NSArray *events = [api eventsCreatedBy:u.fid];
	GHAssertTrue(events.count == 1, @"", @"");
	
	[event destroyRemote];
	[u destroyRemote];
	
}

-(void) testThatAUserCanGetTheNearestEvents{
	Event *e = [self makeEvent];
	[e saveRemote];
	
	Event *e2 = [self makeEvent2];
	[e2 saveRemote];
	
	double lat = 1.352184;                                                                                  
	double lon =  103.819838;
	
	NSArray *events = [api getEventsNearestToLat:lat Lon:lon];
	
	[e destroyRemote];
	[e2 destroyRemote];
	
}


-(void) testThatWeCanGetAnEvent{
	Event *e = [self makeEvent];
	[e saveRemote];
	
	NSString *myId = e.eventId;
	Event* k = [api getEventWithId:myId];
	
	[e destroyRemote];
}

@end